<?php declare(strict_types=1);

/**
 * @author      guosir
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Apis\Admin\Ctl;

use Srv\Apps\Proto\DTO\Auth\AuthReqInfoListDTO;
use Srv\Apps\Proto\DTO\Auth\FrontRoleAddDTO;
use Srv\Apps\Proto\DTO\Auth\FrontRoleEditDTO;
use Srv\Apps\Proto\DTO\Auth\FrontRoleInfoListDTO;
use Srv\Apps\Proto\DTO\Auth\FrontRouteAsyncDTO;
use Srv\Apps\Proto\DTO\Auth\FrontRouteDTO;
use Srv\Apps\Proto\DTO\Auth\FrontRouteListDTO;
use Srv\Apps\Proto\VO\Auth\AuthReqInfoListVO;
use Srv\Apps\Proto\VO\Auth\AuthReqInfoVO;
use Srv\Apps\Proto\VO\Auth\FrontRoleInfoListVO;
use Srv\Apps\Proto\VO\Auth\FrontRoleInfoVO;
use Srv\Apps\Proto\VO\Auth\FrontRouteListVO;
use Srv\Apps\Proto\VO\Auth\FrontRouteVO;
use Srv\Libs\Common\CommArray;
use Srv\Libs\Common\CommJson;
use Srv\Libs\Common\CommTime;
use Srv\Libs\Frame\ControllerAbstract;
use Srv\Libs\Frame\Page;
use Srv\Libs\Storage\DataMysql;

final class AuthCtl extends ControllerAbstract
{
    private ?DataMysql $DbAuto              = null;     // DB-Write

    /**
     * @return static
     * tag
     */
    final public static function tag():self
    {
        $thisObject                         = self::tagGet();
        if($thisObject instanceof self){
            $thisObject->DbAuto             = self::getDbAuto();
        }
        return $thisObject;
    }

    /**
     * @param Page $Page
     * @param array $whereData
     * @return AuthReqInfoListVO|null
     * getReqInfoList
     */
    public function getReqInfoList(Page $Page, array $whereData):?AuthReqInfoListVO
    {
        $limitString        = $Page->getLimitString();
        $whereString        = ' WHERE 1';
        // 检索条件
        if(count($whereData) > 0)foreach ($whereData as $key => $val){
            switch ($key){
                case AuthReqInfoListDTO::_authId:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'takr_id='.intval($val);
                    break;
                case AuthReqInfoListDTO::_key:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'takr_key LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case AuthReqInfoListDTO::_name:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'takr_name LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case AuthReqInfoListDTO::_lock:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'takr_lock='.intval($val);
                    break;
                case AuthReqInfoListDTO::_level:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'takr_level='.intval($val);
                    break;
            }
        }
        $isFail             = false;
        $sql                = 'SELECT SQL_CALC_FOUND_ROWS takr_id, takr_key, takr_name, takr_lock, takr_level FROM '.$this->DbAuto->getTableNameAll('adm_auth_key_record').' ORDER BY takr_id DESC '.$limitString;
        $authReqRecordList  = $this->DbAuto->getData($sql, $isFail);
        $totalNum           = $this->DbAuto->getDataInt('SELECT FOUND_ROWS() as num', 'num');
        if($isFail) return null;
        $AuthReqInfoVOList  = [];
        if(CommArray::isForeach($authReqRecordList)) foreach ($authReqRecordList as $authReqRecord){
            $takrIdItem         = intval($authReqRecord['takr_id']);
            if($takrIdItem < 1) continue;
            $AuthReqInfoVO      = $this->getAuthReqInfoVO($authReqRecord);
            if(!($AuthReqInfoVO instanceof AuthReqInfoVO)) continue;
            $AuthReqInfoVOList[]    = $AuthReqInfoVO;
        }
        $AuthReqInfoListVO  = new AuthReqInfoListVO();
        $AuthReqInfoListVO->setList($AuthReqInfoVOList);
        $AuthReqInfoListVO->setPage($Page->getPageVO($totalNum));
        return $AuthReqInfoListVO;
    }

    /**
     * @param int $takrId
     * @return AuthReqInfoVO|null
     * getAuthReqInfo
     */
    public function getAuthReqInfo(int $takrId): ?AuthReqInfoVO
    {
        $isFail         = false;
        $authReqRecord  = $this->DbAuto->getDataOne('SELECT takr_id, takr_key, takr_name, takr_lock, takr_level FROM '.$this->DbAuto->getTableNameAll('adm_auth_key_record').' WHERE takr_id='.$takrId, $isFail);
        if($isFail || !isset($authReqRecord['takr_id'])) return null;
        return $this->getAuthReqInfoVO($authReqRecord);
    }

    /**
     * @param array $authReqRecord
     * @return AuthReqInfoVO|null
     * getAuthReqInfoVO
     */
    public function getAuthReqInfoVO(array $authReqRecord): ?AuthReqInfoVO
    {
        if(!isset($authReqRecord['takr_id'])) return null;
        $AuthReqInfoVO      = new AuthReqInfoVO();
        $AuthReqInfoVO->setAuthId(intval($authReqRecord['takr_id']));
        $AuthReqInfoVO->setKey(trim($authReqRecord['takr_key']));
        $AuthReqInfoVO->setName(trim($authReqRecord['takr_name']));
        $AuthReqInfoVO->setLock(intval($authReqRecord['takr_lock']));
        $AuthReqInfoVO->setLevel(intval($authReqRecord['takr_level']));
        return $AuthReqInfoVO;
    }

    /**
     * @param array $takrIdList
     * @return array
     * getAuthReqInfoVOList
     */
    public function getAuthReqInfoVOList(array $takrIdList):array
    {
        $AuthReqInfoVOList      = [];
        if(count($takrIdList) < 1) return $AuthReqInfoVOList;
        $isFail                 = false;
        $authReqRecordList      = $this->DbAuto->getData('SELECT takr_id, takr_key, takr_name, takr_lock, takr_level FROM '.$this->DbAuto->getTableNameAll('adm_auth_key_record').' WHERE takr_id IN ('.implode(',', $takrIdList).')', $isFail);
        if($isFail || count($authReqRecordList) < 1) return $AuthReqInfoVOList;
        foreach ($authReqRecordList as $authReqRecord){
            $takrIdItem                     = intval($authReqRecord['takr_id']);
            if($takrIdItem < 1) continue;
            $AuthReqInfoVO                  = $this->getAuthReqInfoVO($authReqRecord);
            if(!($AuthReqInfoVO instanceof AuthReqInfoVO)) continue;
            $AuthReqInfoVOList[$takrIdItem] = $AuthReqInfoVO;
        }
        return $AuthReqInfoVOList;
    }

    /**
     * @param array $setData
     * @return bool
     * reqInfoListAsync
     */
    public function reqInfoListAsync(array $setData): bool
    {
        if(count($setData) < 1) return false;
        $routeList              = $setData[FrontRouteAsyncDTO::_routeList];
        $routeFilterList        = [];
        $routeKeyFilterList     = [];
        foreach ($routeList as $item){
            $routeKeyTrim           = trim($item[FrontRouteDTO::_key]??'');
            $routeNameTrim          = trim($item[FrontRouteDTO::_name]);
            $authKeyList            = $item[FrontRouteDTO::_authKeyList];
            if(strlen($routeKeyTrim) < 1 || strlen($routeNameTrim) < 1 || in_array($routeKeyTrim, $routeKeyFilterList, true)) continue;
            $routeKeyFilterList[]   = $routeKeyTrim;
            $authKeyInfoSrcList     = $this->getAuthKeyInfoSrcByKeyBatch($authKeyList);
            $takrIdList             = array_map('intval', array_column($authKeyInfoSrcList, 'takrId'));
            $routeFilterList[]      = ['routeId' => 0, 'routeKey' => $routeKeyTrim, 'routeName' => $routeNameTrim, 'takrIdList' => $takrIdList];
        }
        $existKeyList           = $this->getFrontRouteSrcByKeyBatch($routeKeyFilterList);
        $addString              = '';
        $updateColumnList       = [];
        $updateIdList           = [];
        $currTime               = CommTime::getTimeStamp();
        foreach ($routeFilterList as $item){
            $takrIdsItem        = CommJson::encodeArray($item['takrIdList']);
            if(isset($existKeyList[$item['routeKey']]) && isset($existKeyList[$item['routeKey']]['afrtId']) && $existKeyList[$item['routeKey']]['afrtId']>0){
                $routeIdItem                                = $existKeyList[$item['routeKey']]['afrtId'];
                $updateIdList[]                             = $routeIdItem;
                if(isset($updateColumnList['afrt_route_name'])){
                    $updateColumnList['afrt_route_name']    .= ' WHEN '.$routeIdItem.' THEN \''.$this->DbAuto->getRealEscapeString($item['routeName']).'\'';
                }else{
                    $updateColumnList['afrt_route_name']    = ' WHEN '.$routeIdItem.' THEN \''.$this->DbAuto->getRealEscapeString($item['routeName']).'\'';
                }
                if(isset($updateColumnList['takr_ids'])){
                    $updateColumnList['takr_ids']           .= ' WHEN '.$routeIdItem.' THEN \''.$this->DbAuto->getRealEscapeString($takrIdsItem).'\'';
                }else{
                    $updateColumnList['takr_ids']           = ' WHEN '.$routeIdItem.' THEN \''.$this->DbAuto->getRealEscapeString($takrIdsItem).'\'';
                }
            }else{
                $addString  .= (strlen($addString) > 0 ? ', ' : ''). '(\''.$this->DbAuto->getRealEscapeString($item['routeKey']).'\', \''.$this->DbAuto->getRealEscapeString($item['routeName']).'\', \''.$this->DbAuto->getRealEscapeString($takrIdsItem).'\', 0, '.$currTime.', '.$currTime.')';
            }
        }
        if(strlen($addString) < 1 && count($updateIdList) < 1) return false;
        $this->DbAuto->startTransaction();
        // 新增前端路由信息
        if(strlen($addString) > 0){
            $isFail         = false;
            $insertSql      = 'INSERT INTO '.$this->DbAuto->getTableNameAll('adm_front_route_record').' (afrt_route_key, afrt_route_name, takr_ids, afrt_delete, afrt_create_time, afrt_update_time) VALUES '.$addString.' ON DUPLICATE KEY UPDATE afrt_route_name=VALUES(afrt_route_name), takr_ids=VALUES(takr_ids), afrt_delete=VALUES(afrt_delete), afrt_update_time=VALUES(afrt_update_time)';
            $lastKeyId      = $this->DbAuto->getDataId($insertSql, $isFail);
            if($isFail || $lastKeyId < 1){
                $this->DbAuto->backTransaction();
                return false;
            }
        }
        // 更新前端路由信息
        if(count($updateIdList) > 0){
            $setString      = '';
            foreach ($updateColumnList as $key => $str){
                $setString  .= (strlen($setString) > 0 ? ', ':'').$key.' = CASE afrt_id '.$str.' END';
            }
            $isFail         = false;
            $updateSql      = 'UPDATE '.$this->DbAuto->getTableNameAll('adm_front_route_record').' SET '.$setString.', afrt_update_time='.$currTime.' WHERE afrt_id IN('.implode(',', $updateIdList).')';
            $this->DbAuto->getDataNum($updateSql, $isFail);
            if($isFail){
                $this->DbAuto->backTransaction();
                return false;
            }
        }
        $this->DbAuto->commitTransaction();
        return true;
    }

    /**
     * @param array $keyList
     * @return array
     * getAuthKeyInfoSrcByKeyBatch
     */
    public function getAuthKeyInfoSrcByKeyBatch(array $keyList):array
    {
        if(count($keyList) < 1) return [];
        $keyListString          = '';
        foreach ($keyList as $keyStr){
            $reqKeyStrTrim      = trim($keyStr);
            if(strlen($keyStr) < 1) continue;
            $keyListString      .= (strlen($keyListString) > 0 ? ', ' : ''). '\''.$this->DbAuto->getRealEscapeString($reqKeyStrTrim).'\'';
        }
        $isFail             = false;
        $sql                = 'SELECT takr_id, takr_key, takr_name, takr_lock, takr_level FROM '.$this->DbAuto->getTableNameAll('adm_auth_key_record').' WHERE takr_key IN ('.$keyListString.')';
        $list               = $this->DbAuto->getData($sql, $isFail);
        $listData           = [];
        if(!$isFail && count($list) > 0) foreach ($list as $item){
            $takrIdItem     = intval($item['takr_id']??0);
            $takrKeyItem    = trim($item['takr_key']??'');
            if($takrIdItem < 1 || strlen($takrKeyItem) < 1) continue;
            $listData[$takrKeyItem] = [
                'takrId'    => $takrIdItem,
                'key'       => $takrKeyItem,
                'name'      => trim($item['takr_name']),
                'lock'      => intval($item['takr_lock']),
                'level'     => intval($item['takr_level']),
            ];
        }
        return $listData;
    }

    /**
     * @param array $reqIdList
     * @return array
     * getAuthKeyInfoSrcByIdBatch
     */
    public function getAuthKeyInfoSrcByIdBatch(array $reqIdList):array
    {
        if(count($reqIdList) < 1) return [];
        $isFail             = false;
        $sql                = 'SELECT takr_id, takr_key, takr_name, takr_lock, takr_level FROM '.$this->DbAuto->getTableNameAll('adm_auth_key_record').' WHERE takr_id IN ('.implode(',', $reqIdList).')';
        $list               = $this->DbAuto->getData($sql, $isFail);
        $listData           = [];
        if(!$isFail && count($list) > 0) foreach ($list as $item){
            $takrIdItem     = intval($item['takr_id']??0);
            $takrKeyItem    = trim($item['takr_key']??'');
            if($takrIdItem < 1 || strlen($takrKeyItem) < 1) continue;
            $listData[$takrKeyItem] = [
                'takrId'    => $takrIdItem,
                'key'       => $takrKeyItem,
                'name'      => trim($item['takr_name']),
                'lock'      => intval($item['takr_lock']),
                'level'     => intval($item['takr_level']),
            ];
        }
        return $listData;
    }

    /**
     * @param array $roleIdList
     * @return array
     * getFrontRoleInfoSrcByIdBatch
     */
    public function getFrontRoleInfoSrcByIdBatch(array $roleIdList):array
    {
        if(count($roleIdList) < 1) return [];
        $isFail     = false;
        $sql        = 'SELECT afro_id, afro_name, afro_status, afrt_ids, afro_create_time, afro_update_time FROM '.$this->DbAuto->getTableNameAll('adm_front_role_record').' WHERE afro_id IN('.implode(',', $roleIdList).') AND afro_delete=0';
        $list       = $this->DbAuto->getData($sql, $isFail);
        $listData   = [];
        if(!$isFail && count($list) > 0) foreach ($list as $item){
            $afroIdItem     = intval($item['afro_id']??0);
            if($afroIdItem < 1) continue;
            $listData[$afroIdItem]  = [
                'afroId'            => $afroIdItem,
                'name'              => trim($item['afro_name']),
                'status'            => trim($item['afro_status']),
                'afrtIds'           => trim($item['afrt_ids']),
                'createTime'        => intval($item['afro_create_time']),
                'updateTime'        => intval($item['afro_update_time']),
            ];
        }
        return $listData;
    }

    /**
     * @param int $roleId
     * @return array
     * getFrontRoleInfoSrc
     */
    public function getFrontRoleInfoSrc(int $roleId):array
    {
        if($roleId < 1) return [];
        $isFail         = false;
        $sql            = 'SELECT afro_id, afro_name, afro_status, afrt_ids, afro_create_time, afro_update_time FROM '.$this->DbAuto->getTableNameAll('adm_front_role_record').' WHERE afro_id='.$roleId.' AND afro_delete=0';
        $roleInfoRecord = $this->DbAuto->getDataOne($sql, $isFail);
        if($isFail || !isset($roleInfoRecord['afro_id'])) return [];
        return $roleInfoRecord;
    }

    /**
     * @param int $roleId
     * @return FrontRoleInfoVO|null
     * getFontRoleInfo
     */
    public function getFontRoleInfo(int $roleId):?FrontRoleInfoVO
    {
        $roleInfoRecord = $this->getFrontRoleInfoSrc($roleId);
        if(!isset($roleInfoRecord['afro_id'])) return null;
        return $this->getFrontRoleInfoVO($roleInfoRecord);
    }

    /**
     * @param array $roleInfoRecord
     * @return FrontRoleInfoVO|null
     * getFrontRoleInfoVO
     */
    public function getFrontRoleInfoVO(array $roleInfoRecord):?FrontRoleInfoVO
    {
        if(!isset($roleInfoRecord['afro_id'])) return null;
        $FrontRoleInfoVO     = new FrontRoleInfoVO();
        $FrontRoleInfoVO->setRoleId(intval($roleInfoRecord['afro_id']));
        $FrontRoleInfoVO->setName($roleInfoRecord['afro_name']);
        $FrontRoleInfoVO->setStatus(intval($roleInfoRecord['afro_status']));
        $afrtIdList         = CommJson::decodeArray($roleInfoRecord['afrt_ids']);
        $routeList          = $this->getFrontRouteVOList($afrtIdList);
        if(count($routeList) > 0) $FrontRoleInfoVO->setRouteList($routeList);
        $FrontRoleInfoVO->setCreateTime(intval($roleInfoRecord['afro_create_time']));
        $FrontRoleInfoVO->setUpdateTime(intval($roleInfoRecord['afro_update_time']));
        return $FrontRoleInfoVO;
    }

    /**
     * @param array $roleIdList
     * @return array
     * getFrontRoleInfoVOList
     */
    public function getFrontRoleInfoVOList(array $roleIdList):array
    {
        if(count($roleIdList) < 1) return [];
        $isFail     = false;
        $sql        = 'SELECT afro_id, afro_name, afro_status, afrt_ids, afro_create_time, afro_update_time FROM '.$this->DbAuto->getTableNameAll('adm_front_role_record').' WHERE afro_id IN('.implode(',', $roleIdList).') AND afro_delete=0';
        $list       = $this->DbAuto->getData($sql, $isFail);
        $listData   = [];
        if(!$isFail && count($list) > 0) foreach ($list as $item){
            $afroIdItem             = intval($item['afro_id']??0);
            if($afroIdItem < 1) continue;
            $FrontRoleInfoVO        = $this->getFrontRoleInfoVO($item);
            if(!($FrontRoleInfoVO instanceof FrontRoleInfoVO)) continue;
            $listData[$afroIdItem]  = $FrontRoleInfoVO;
        }
        return $listData;
    }

    /**
     * @param Page $Page
     * @param array $whereData
     * @return FrontRoleInfoListVO|null
     * getFrontRoleInfoList
     */
    public function getFrontRoleInfoList(Page $Page, array $whereData):?FrontRoleInfoListVO
    {
        $limitString        = $Page->getLimitString();
        $whereString        = ' WHERE afro_delete=0';
        // 检索条件
        if(count($whereData) > 0) foreach ($whereData as $key => $val){
            switch ($key){
                case FrontRoleInfoListDTO::_roleId:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'afro_id='.intval($val);
                    break;
                case FrontRoleInfoListDTO::_name:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'afro_name LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case FrontRoleInfoListDTO::_status:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'afro_status='.intval($val);
                    break;
            }
        }
        $isFail                 = false;
        $sql                    = 'SELECT SQL_CALC_FOUND_ROWS afro_id, afro_name, afro_status, afrt_ids, afro_create_time, afro_update_time FROM '.$this->DbAuto->getTableNameAll('adm_front_role_record').$whereString.' ORDER BY afro_id DESC '.$limitString;
        $list                   = $this->DbAuto->getData($sql, $isFail);
        $totalNum               = $this->DbAuto->getDataInt('SELECT FOUND_ROWS() as num', 'num');
        if($isFail) return null;
        $FrontRoleInfoVOList    = [];
        if(CommArray::isForeach($list))foreach($list as $item){
            $afroIdItem             = intval($item['afro_id']??0);
            if($afroIdItem < 1) continue;
            $FrontRoleInfoVO        = $this->getFrontRoleInfoVO($item);
            if(!($FrontRoleInfoVO instanceof FrontRoleInfoVO)) continue;
            $FrontRoleInfoVOList[]  = $FrontRoleInfoVO;
        }
        $FrontRoleInfoListVO = new FrontRoleInfoListVO();
        $FrontRoleInfoListVO->setList($FrontRoleInfoVOList);
        $FrontRoleInfoListVO->setPage($Page->getPageVO($totalNum));
        return $FrontRoleInfoListVO;
    }

    /**
     * @param array $setData
     * @return int
     * frontRoleAdd
     */
    public function frontRoleAdd(array $setData):int
    {
        if(count($setData) < 1) return 0;
        $setString      = '';
        foreach ($setData as $key => $val){
            switch ($key){
                case FrontRoleAddDTO::_name:
                    $setString          .= (strlen($setString) > 0 ? ',' : '').'afro_name=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case FrontRoleAddDTO::_status:
                    $setString          .= (strlen($setString) > 0 ? ',' : '').'afro_status='.intval($val);
                    break;
                case FrontRoleAddDTO::_routeIdList:
                    $routeIdList        = [];
                    if(count($val) > 0){
                        $frontRouteList = $this->getFrontRouteSrcByIdBatch($val);
                        $routeIdList    = array_map('intval', array_column($frontRouteList, 'afrtId'));
                    }
                    $routeIdListJson    = CommJson::encodeArray($routeIdList);
                    $setString          .= (strlen($setString) > 0 ? ',' : '').'afrt_ids=\''.$this->DbAuto->getRealEscapeString($routeIdListJson).'\'';
                    break;
            }
        }
        if(strlen($setString) < 1) return 0;
        $currTime       = CommTime::getTimeStamp();
        $isFail         = false;
        $sql            = 'INSERT INTO '.$this->DbAuto->getTableNameAll('adm_front_role_record').' SET '.$setString.', afro_delete=0, afro_create_time='.$currTime.', afro_update_time='.$currTime;
        $roleId         = $this->DbAuto->getDataId($sql, $isFail);
        if($isFail || $roleId < 1) return 0;
        return $roleId;
    }

    /**
     * @param int $roleId
     * @param array $setData
     * @return bool
     * frontRoleEdit
     */
    public function frontRoleEdit(int $roleId, array $setData):bool
    {
        if($roleId < 1 || count($setData) < 1) return false;
        $setString      = '';
        foreach ($setData as $key => $val){
            switch ($key){
                case FrontRoleEditDTO::_name:
                    $setString          .= (strlen($setString) > 0 ? ',' : '').'afro_name=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case FrontRoleEditDTO::_status:
                    $setString          .= (strlen($setString) > 0 ? ',' : '').'afro_status='.intval($val);
                    break;
                case FrontRoleEditDTO::_routeIdList:
                    $routeIdList        = [];
                    if(count($val) > 0){
                        $frontRouteList = $this->getFrontRouteSrcByIdBatch($val);
                        $routeIdList    = array_map('intval', array_column($frontRouteList, 'afrtId'));
                    }
                    $routeIdListJson    = CommJson::encodeArray($routeIdList);
                    $setString          .= (strlen($setString) > 0 ? ',' : '').'afrt_ids=\''.$this->DbAuto->getRealEscapeString($routeIdListJson).'\'';
                    break;
            }
        }
        if(strlen($setString) < 1) return false;
        $currTime       = CommTime::getTimeStamp();
        $isFail         = false;
        $sql            = 'UPDATE '.$this->DbAuto->getTableNameAll('adm_front_role_record').' SET '.$setString.', afro_update_time='.$currTime.' WHERE afro_id='.$roleId.' AND afro_delete=0';
        $this->DbAuto->getDataNum($sql, $isFail);
        if($isFail) return false;
        return true;
    }

    /**
     * @param array $afrtIdList
     * @return array
     * getFrontRouteVOList
     */
    public function getFrontRouteVOList(array $afrtIdList):array
    {
        $FrontRouteVOList       = [];
        if(count($afrtIdList) < 1) return $FrontRouteVOList;
        $isFail                 = false;
        $list                   = $this->DbAuto->getData('SELECT afrt_id, afrt_route_key, afrt_route_name, takr_ids, afrt_create_time, afrt_update_time FROM '.$this->DbAuto->getTableNameAll('adm_front_route_record').' WHERE afrt_id IN ('.implode(',', $afrtIdList).') AND afrt_delete=0', $isFail);
        if($isFail || count($list) < 1) return $FrontRouteVOList;
        foreach ($list as $item){
            $afrtIdItem                     = intval($item['afrt_id']);
            if($afrtIdItem < 1) continue;
            $FrontRouteVO                   = $this->getFrontRouteInfoVO($item);
            if(!($FrontRouteVO instanceof FrontRouteVO)) continue;
            $FrontRouteVOList[$afrtIdItem]  = $FrontRouteVO;
        }
        return $FrontRouteVOList;
    }

    /**
     * @param array $routeIdList
     * @return array
     * getFrontRouteSrcByIdBatch
     */
    public function getFrontRouteSrcByIdBatch(array $routeIdList):array
    {
        if(count($routeIdList) < 1) return [];
        $isFail             = false;
        $sql                = 'SELECT afrt_id, afrt_route_key, afrt_route_name, takr_ids, afrt_create_time, afrt_update_time FROM '.$this->DbAuto->getTableNameAll('adm_front_route_record').' WHERE afrt_id IN ('.implode(',', $routeIdList).') AND afrt_delete=0';
        $list               = $this->DbAuto->getData($sql, $isFail);
        $listData           = [];
        if(!$isFail && count($list) > 0) foreach ($list as $item){
            $afrtIdItem     = intval($item['afrt_id']??0);
            $afrtKeyItem    = trim($item['afrt_route_key']??'');
            if($afrtIdItem < 1 || strlen($afrtKeyItem) < 1) continue;
            $listData[$afrtKeyItem] = [
                'afrtId'    => $afrtIdItem,
                'key'       => $afrtKeyItem,
                'name'      => trim($item['afrt_route_name']),
                'takrIds'   => CommJson::decodeArray($item['takr_ids']),
            ];
        }
        return $listData;
    }

    /**
     * @param array $frontRouteRecord
     * @return FrontRouteVO|null
     * getFrontRouteInfoVO
     */
    public function getFrontRouteInfoVO(array $frontRouteRecord): ?FrontRouteVO
    {
        if(!isset($frontRouteRecord['afrt_id'])) return null;
        $FrontRouteVO       = new FrontRouteVO();
        $FrontRouteVO->setRouteId(intval($frontRouteRecord['afrt_id']));
        $FrontRouteVO->setKey(trim($frontRouteRecord['afrt_route_key']));
        $FrontRouteVO->setName(trim($frontRouteRecord['afrt_route_name']));
        $takrIds            = CommJson::decodeArray($frontRouteRecord['takr_ids']??'[]');
        $authKeyList        = $this->getAuthKeyInfoSrcByIdBatch($takrIds);
        $FrontRouteVO->setAuthKeyList(array_column($authKeyList, 'key'));
        return $FrontRouteVO;
    }

    /**
     * @param array $keyList
     * @return array
     * getFrontRouteSrcByKeyBatch
     */
    public function getFrontRouteSrcByKeyBatch(array $keyList):array
    {
        if(count($keyList) < 1) return [];
        $keyListString          = '';
        foreach ($keyList as $keyStr){
            $reqKeyStrTrim      = trim($keyStr);
            if(strlen($keyStr) < 1) continue;
            $keyListString      .= (strlen($keyListString) > 0 ? ', ' : ''). '\''.$this->DbAuto->getRealEscapeString($reqKeyStrTrim).'\'';
        }
        $isFail             = false;
        $sql                = 'SELECT afrt_id, afrt_route_key, afrt_route_name, takr_ids, afrt_create_time, afrt_update_time FROM '.$this->DbAuto->getTableNameAll('adm_front_route_record').' WHERE afrt_route_key IN ('.$keyListString.') AND afrt_delete=0';
        $list               = $this->DbAuto->getData($sql, $isFail);
        $listData           = [];
        if(!$isFail && count($list) > 0) foreach ($list as $item){
            $afrtIdItem     = intval($item['afrt_id']??0);
            $afrtKeyItem    = trim($item['afrt_route_key']??'');
            if($afrtIdItem < 1 || strlen($afrtKeyItem) < 1) continue;
            $listData[$afrtKeyItem] = [
                'afrtId'    => $afrtIdItem,
                'key'       => $afrtKeyItem,
                'name'      => trim($item['afrt_route_name']),
                'takrIds'   => CommJson::decodeArray($item['takr_ids']),
            ];
        }
        return $listData;
    }

    /**
     * @param Page $Page
     * @param array $whereData
     * @return FrontRouteListVO|null
     * getFrontRouteList
     */
    public function getFrontRouteList(Page $Page, array $whereData):?FrontRouteListVO
    {
        $limitString        = $Page->getLimitString();
        $whereString        = ' WHERE afrt_delete=0';
        // 检索条件
        if(count($whereData) > 0)foreach ($whereData as $key => $val){
            switch ($key){
                case FrontRouteListDTO::_routeId:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'afrt_id='.intval($val);
                    break;
                case FrontRouteListDTO::_key:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'afrt_route_key LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case FrontRouteListDTO::_name:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'afrt_route_name LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
            }
        }
        $isFail                 = false;
        $sql                    = 'SELECT SQL_CALC_FOUND_ROWS afrt_id, afrt_route_key, afrt_route_name, takr_ids, afrt_create_time, afrt_update_time FROM '.$this->DbAuto->getTableNameAll('adm_front_route_record').$whereString.' ORDER BY afrt_id DESC '.$limitString;
        $list                   = $this->DbAuto->getData($sql, $isFail);
        $totalNum               = $this->DbAuto->getDataInt('SELECT FOUND_ROWS() as num', 'num');
        if($isFail) return null;
        $FrontRouteVOList       = [];
        if(CommArray::isForeach($list))foreach ($list as $item){
            $afrtIdItem         = intval($item['afrt_id']);
            if($afrtIdItem < 1) continue;
            $FrontRouteVO       = $this->getFrontRouteInfoVO($item);
            if(!($FrontRouteVO instanceof FrontRouteVO)) continue;
            $FrontRouteVOList[] = $FrontRouteVO;
        }
        $FrontRouteListVO  = new FrontRouteListVO();
        $FrontRouteListVO->setList($FrontRouteVOList);
        $FrontRouteListVO->setPage($Page->getPageVO($totalNum));
        return $FrontRouteListVO;
    }
}